package com.timesheet.gui.efforttracker.controllers;

import java.util.Calendar;
import java.util.Date;
import java.util.List;

import org.eclipse.core.databinding.DataBindingContext;
import org.eclipse.core.databinding.UpdateValueStrategy;
import org.eclipse.core.databinding.beans.BeansObservables;
import org.eclipse.core.databinding.beans.PojoProperties;
import org.eclipse.core.databinding.observable.value.IObservableValue;
import org.eclipse.jface.databinding.swt.ISWTObservableValue;
import org.eclipse.jface.databinding.swt.SWTObservables;
import org.eclipse.jface.databinding.viewers.IViewerObservableValue;
import org.eclipse.jface.databinding.viewers.ViewersObservables;
import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.jface.fieldassist.ControlDecoration;
import org.eclipse.jface.fieldassist.FieldDecoration;
import org.eclipse.jface.fieldassist.FieldDecorationRegistry;
import org.eclipse.jface.viewers.ArrayContentProvider;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.widgets.Combo;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.DateTime;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.MessageBox;
import org.eclipse.swt.widgets.Text;

import com.example.timesheet.uitl.DateUtil;
import com.example.timesheet.uitl.TaskConstants;
import com.example.timesheet.uitl.TaskUtils;
import com.timesheet.gui.efforttracker.composite.CreateNewEffortComposite;
import com.timesheet.gui.efforttracker.utils.EffortTrackerUtil;
import com.timesheet.gui.efforttracker.validators.NotNullValidator;
import com.timesheet.server.common.models.EffortTrackerDTO;
import com.timesheet.server.common.models.view.EffortTrackerViewModel;
import com.timesheet.server.common.models.view.EffortTrackerViewModelContainer;
import com.timesheet.server.common.session.Session;
import com.timesheet.server.core.mapper.Mapper3;
import com.timesheet.serverice.EffortTrackerService;

public class CreateNewEffortController {

    String taskType = "";

    String taskPhase = "";

    String taskNo = "";

    private EffortTrackerService effortTrackerService = new EffortTrackerService();

    private CreateNewEffortComposite createNewEffortComposite;

    private EffortTrackerViewModelContainer effortTrackerViewModelContainer = EffortTrackerViewModelContainer
            .getInstance();

    private EffortTrackerViewModel effortTrackerViewModel = new EffortTrackerViewModel();

    private Combo cmbTasktype = null;

    private Combo cmbTaskphase = null;

    private Text txtTaskNo = null;

    private Text txtHours;

    private Combo cmbTaskStatus = null;

    public CreateNewEffortController(
            CreateNewEffortComposite createNewEffortComposite) {
        this.createNewEffortComposite = createNewEffortComposite;

        initialize(createNewEffortComposite);

        setValues();

        loadDailyEfforForAWeek();

        initDataBinding();

        performActions();

    }

    private void initialize(CreateNewEffortComposite createNewEffortComposite) {
        cmbTasktype = createNewEffortComposite.getCmbTaskType();
        cmbTaskphase = createNewEffortComposite.getCmbTaskPhase();
        txtTaskNo = createNewEffortComposite.getTxtTaskNo();
        txtHours = createNewEffortComposite.getTxtHours();
        taskType = cmbTasktype.getText();
        taskPhase = cmbTaskphase.getText();
        taskNo = txtTaskNo.getText();
        cmbTaskStatus = createNewEffortComposite.getCmbStatus();
    }

    /**
     * 
     */
    public DataBindingContext initDataBinding() {

        DataBindingContext dbx = new DataBindingContext();

        // tasktype
        IViewerObservableValue observeTaskTypeCombo = ViewersObservables
                .observeSingleSelection(createNewEffortComposite
                        .getComboTaskTypeViewer());
        IObservableValue myModel = PojoProperties.value("taskType").observe(
                effortTrackerViewModel);
        dbx.bindValue(observeTaskTypeCombo, myModel);

        // taskno
        NotNullValidator notNullValidator = new NotNullValidator(
                "Please enter Taskno", getControlDecoration(txtTaskNo,
                        "Please enter Taskno"));
        ISWTObservableValue observeTxtNo = SWTObservables.observeText(
                txtTaskNo, SWT.Modify);
        IObservableValue observeModelTaskNo = BeansObservables.observeValue(
                effortTrackerViewModel, "taskNo");
        dbx.bindValue(observeTxtNo, observeModelTaskNo,
                null, null);

        // tasktype
        IViewerObservableValue observeTaskTPhaseCombo = ViewersObservables
                .observeSingleSelection(createNewEffortComposite
                        .getComboTaskPhaseViewer());
        IObservableValue taskPhaseModel = PojoProperties.value("taskPhase")
                .observe(effortTrackerViewModel);
        dbx.bindValue(observeTaskTPhaseCombo, taskPhaseModel);

        // hours
        ISWTObservableValue observeTxtHours = SWTObservables.observeText(
                txtHours, SWT.Modify);
        IObservableValue observeModelHours = BeansObservables.observeValue(
                effortTrackerViewModel, "hours");
        dbx.bindValue(observeTxtHours, observeModelHours);

        // missing datetime

        // status
        IViewerObservableValue observeCmbStatus = ViewersObservables
                .observeSingleSelection(createNewEffortComposite
                        .getComboStatusViewer());
        IObservableValue observeModelStatus = PojoProperties.value("status")
                .observe(effortTrackerViewModel);
        dbx.bindValue(observeCmbStatus, observeModelStatus);

        // description
        ISWTObservableValue observeTxtDesc = SWTObservables.observeText(
                createNewEffortComposite.getTxtDescription(), SWT.Modify);
        IObservableValue observeModelTaskDesc = BeansObservables.observeValue(
                effortTrackerViewModel, "taskDescription");
        dbx.bindValue(observeTxtDesc, observeModelTaskDesc);

        return dbx;

    }

    /**
     * 
     */
    private void loadDailyEfforForAWeek() {
        Date weekDate = DateUtil.getWeekDate(createWeekDate()).getTime();
        loadDailyEffortsForAWeekDataToTable(new EffortTrackerViewModel(),
                weekDate);
    }

    /**
     * 
     */
    private void setValues() {

        createNewEffortComposite.getComboStatusViewer().setContentProvider(
                ArrayContentProvider.getInstance());
        createNewEffortComposite.getComboStatusViewer().setInput(
                TaskUtils.getTaskStatus());

        createNewEffortComposite.getComboTaskPhaseViewer().setContentProvider(
                ArrayContentProvider.getInstance());
        createNewEffortComposite.getComboTaskPhaseViewer().setInput(
                TaskUtils.getTaskPhases());

        createNewEffortComposite.getComboTaskTypeViewer().setContentProvider(
                ArrayContentProvider.getInstance());
        createNewEffortComposite.getComboTaskTypeViewer().setInput(
                TaskUtils.getEffortFillTaskTypes());

    }

    /**
     * 
     */
    private void performActions() {

        createNewEffortComposite.getBtnSave().addSelectionListener(
                new SelectionAdapter() {

                    @Override
                    public void widgetSelected(SelectionEvent e) {
                        save();
                    }
                });

        createNewEffortComposite.getCmbTaskType().addSelectionListener(
                new SelectionAdapter() {

                    @Override
                    public void widgetSelected(SelectionEvent e) {
                        doDisableOperation();
                    }

                });

        createNewEffortComposite.getDateTime().addSelectionListener(
                new SelectionAdapter() {

                    @Override
                    public void widgetSelected(SelectionEvent e) {
                        DateTime dateTime = (DateTime) e.widget;
                        System.out.println(dateTime.getDay()
                                + dateTime.getMonth() + dateTime.getYear());
                        Calendar createDate2 = DateUtil.createDate2(
                                dateTime.getDay(), (dateTime.getMonth() + 1),
                                dateTime.getYear());
                        Calendar weekDate = DateUtil.getWeekDate(createDate2);
                        List<EffortTrackerDTO> wsrList = effortTrackerService
                                .getWSR(Session.INSTANCE.getUser(), "ABSLIFE",
                                        weekDate.getTime());
                        List<EffortTrackerDTO> dailyEffortList = effortTrackerService
                                .getDailyEffortsForAWeekend(
                                        Session.INSTANCE.getUser(), "ABSLIFE",
                                        weekDate.getTime());
                        effortTrackerViewModelContainer
                                .setWsrList(convertDtoToViewModel(wsrList));
                        effortTrackerViewModelContainer
                                .setList(convertDtoToViewModel(dailyEffortList));
                        effortTrackerViewModelContainer.setWeekDate(weekDate
                                .getTime());

                    }
                });

    }

    private void save() {
        int day = createNewEffortComposite.getDateTime().getDay();
        int month = createNewEffortComposite.getDateTime().getMonth();
        int year = createNewEffortComposite.getDateTime().getYear();
        // usually date time widget's month gives -1
        month++;
        Calendar cal = DateUtil.createDate2(day, month, year);
        Date dayDate = DateUtil.createDate(day, month, year);
        Date weekDate = DateUtil.getWeekDate(cal).getTime();
        effortTrackerViewModel.setDayDate(dayDate);
        effortTrackerViewModel.setEmployeeId(Session.INSTANCE.getUser());
        effortTrackerViewModel.setProjectId(Session.INSTANCE.getProjectId());
        effortTrackerViewModel.setWeekDate(weekDate);
        effortTrackerViewModel.setActive("Active");

        /*
         * if (!canSaveObject()) {
         * 
         * return; }
         */
        EffortTrackerDTO effortTrackerDto = Mapper3.map(new EffortTrackerDTO(),
                effortTrackerViewModel);

        if (canSave()) {

            try {
                // boolean isSuccess = false;

                boolean isSuccess = effortTrackerService
                        .fillEfforts(effortTrackerDto);

                if (isSuccess) {
                    System.out.println("weektime: " + weekDate);
                    loadDailyEffortsForAWeekDataToTable(effortTrackerViewModel,
                            weekDate);
                    effortTrackerViewModelContainer.refresh();

                }
            } catch (Exception exception) {
                exception.printStackTrace();
            }
        }
    }

    private boolean canSave() {        

        boolean taskTypeNotNull = checkNullOrEmpty(effortTrackerViewModel
                .getTaskType());
        boolean isTaskNoNotNull = checkNullOrEmpty(effortTrackerViewModel
                .getTaskNo());
        boolean taskPhaseNotNull = checkNullOrEmpty(effortTrackerViewModel
                .getTaskPhase());
        boolean hours = !(isNumeric(""+effortTrackerViewModel.getHours())) || effortTrackerViewModel.getHours()==0 ;

        boolean isStatusNotNull = checkNullOrEmpty(effortTrackerViewModel
                .getStatus());
        if (taskTypeNotNull) {
            MessageDialog.openInformation(
                    Display.getDefault().getActiveShell(), "Information",
                    "Please select tasktype");
            return false;
        }
        if (isTaskNoNotNull) {
            MessageDialog.openInformation(
                    Display.getDefault().getActiveShell(), "Information",
                    "Please select Tasknumber");
            return false;
        }

        if (taskPhaseNotNull) {
            MessageDialog.openInformation(
                    Display.getDefault().getActiveShell(), "Information",
                    "Please select task phase");
            return false;
        }

        if (hours) {
            MessageDialog.openInformation(
                    Display.getDefault().getActiveShell(), "Information",
                    "Please enter hours");
            return false;
        }

        if (isStatusNotNull) {
            MessageDialog.openInformation(
                    Display.getDefault().getActiveShell(), "Information",
                    "Please select status");
            return false;
        }

        // effortTrackerViewModel.get

        /*
         * if(){
         * 
         * }
         */

        return true;
    }

    private boolean checkNullOrEmpty(String value) {        

        return value == null || value.length() == 0;

    }

    private Calendar createWeekDate() {
        int day = createNewEffortComposite.getDateTime().getDay();
        int month = createNewEffortComposite.getDateTime().getMonth();
        int year = createNewEffortComposite.getDateTime().getYear();
        Calendar cal = Calendar.getInstance();
        cal.set(year, month, day);

        return cal;
    }

    private void loadDailyEffortsForAWeekDataToTable(
            EffortTrackerViewModel effortTrackerViewModel, Date time) {
        List<EffortTrackerDTO> effortsWSRList = effortTrackerService
                .getDailyEffortsForAWeekend(Session.INSTANCE.getUser(),
                        "ABSLIFE", time);

        List<EffortTrackerViewModel> modelList = convertDtoToViewModel(effortsWSRList);
        effortTrackerViewModelContainer.setList(modelList);
        effortTrackerViewModelContainer.add(effortTrackerViewModel);
    }

    private List<EffortTrackerViewModel> convertDtoToViewModel(
            List<EffortTrackerDTO> effortsWSR) {
        return EffortTrackerUtil.convertDtoListToViewModelList(effortsWSR);
    }

    private void doDisableOperation() {

        if (TaskConstants.FULLDAY_LEAVE.equals(cmbTasktype.getText())) {
            taskType = TaskConstants.FULLDAY_LEAVE;
            taskPhase = TaskConstants.FULLDAY_LEAVE;
            taskNo = "" + TaskConstants.FULLDAY_LEAVE_CODE;
            cmbTaskphase.setText(TaskUtils.getTaskPhases()[0]);
            cmbTaskStatus.setText(TaskUtils.getTaskStatus()[0]);
            cmbTaskphase.setEnabled(false);
            txtTaskNo.setEnabled(false);
            txtTaskNo.setText("");
            effortTrackerViewModel.setTaskNo(""
                    + TaskConstants.FULLDAY_LEAVE_CODE);
            txtHours.setText("8");
            txtHours.setEnabled(false);

        } else if (TaskConstants.HALFDAY_LEAVE.equals(cmbTasktype.getText())) {
            taskType = TaskConstants.HALFDAY_LEAVE;
            taskPhase = TaskConstants.HALFDAY_LEAVE;
            taskNo = "" + TaskConstants.HALFDAY_LEAVE_CODE;
            cmbTaskphase.setEnabled(false);
            txtTaskNo.setText("");
            effortTrackerViewModel.setTaskNo(""
                    + TaskConstants.HALFDAY_LEAVE_CODE);
            txtTaskNo.setEnabled(false);
            txtHours.setText("4");
            txtHours.setEnabled(false);
        } else if (TaskConstants.TEAM_MEETING.equals(cmbTasktype.getText())) {
            taskType = TaskConstants.TEAM_MEETING;
            taskPhase = TaskConstants.TEAM_MEETING;
            taskNo = "" + TaskConstants.TEAM_MEETING_CODE;
            cmbTaskphase.setEnabled(false);
            txtTaskNo.setText(taskNo);
            txtTaskNo.setEnabled(false);
        } else if (TaskConstants.MISCELLENEOUS_PROJECT_ACTIVITY
                .equals(cmbTasktype.getText())) {
            taskType = TaskConstants.MISCELLENEOUS_PROJECT_ACTIVITY;
            taskPhase = TaskConstants.MISCELLENEOUS_PROJECT_ACTIVITY;
            taskNo = "" + TaskConstants.MISCELLENEOUS_PROJECT_ACTIVITY_CODE;
            cmbTaskphase.setEnabled(false);
            txtTaskNo.setText(taskNo);
            txtTaskNo.setEnabled(false);
        } else if (TaskConstants.ALL_HANDS_MEETING
                .equals(cmbTasktype.getText())) {
            taskType = TaskConstants.ALL_HANDS_MEETING;
            taskPhase = TaskConstants.ALL_HANDS_MEETING;
            taskNo = "" + TaskConstants.ALL_HANDS_MEETING_CODE;
            cmbTaskphase.setEnabled(false);
            txtTaskNo.setText(taskNo);
            txtTaskNo.setEnabled(false);
        } else if (TaskConstants.MACHINE_SETUP.equals(cmbTasktype.getText())) {
            taskType = TaskConstants.MACHINE_SETUP;
            taskPhase = TaskConstants.MACHINE_SETUP;
            taskNo = "" + TaskConstants.MACHINE_SETUP_CODE;
            cmbTaskphase.setEnabled(false);
            txtTaskNo.setText(taskNo);
            txtTaskNo.setEnabled(false);
        } else if (TaskConstants.SCRUM.equals(cmbTasktype.getText())) {
            taskType = TaskConstants.TECHNICAL_TASKS;
            taskPhase = TaskConstants.TECHNICAL_TASKS;
            taskNo = "" + TaskConstants.TECHNICAL_TASKS_CODE;
            cmbTaskphase.setEnabled(false);
            txtTaskNo.setText(taskNo);
            txtTaskNo.setEnabled(false);
        } else if (TaskConstants.TECHNICAL_TASKS.equals(cmbTasktype.getText())) {
            taskType = TaskConstants.SCRUM;
            taskPhase = TaskConstants.SCRUM;
            taskNo = "" + TaskConstants.SCRUM_CODE;
            cmbTaskphase.setEnabled(false);
            txtTaskNo.setText(taskNo);
            txtTaskNo.setEnabled(false);
        } else {
            taskType = cmbTasktype.getText();
            taskPhase = cmbTaskphase.getText();
            taskNo = txtTaskNo.getText();
            cmbTaskphase.setEnabled(true);
            txtTaskNo.setText(taskNo);
            txtTaskNo.setEnabled(true);
            txtHours.setText("");
            txtHours.setEnabled(true);

        }

    }

    public boolean canSaveObject() {
        if (this.effortTrackerViewModel != null) {

            boolean isTaskTypeNull = effortTrackerViewModel.getTaskType() == null;
            boolean isTaskNoNull = (effortTrackerViewModel.getTaskNo() == null)
                    || effortTrackerViewModel.getTaskNo().isEmpty();
            boolean isStatusNull = effortTrackerViewModel.getStatus() == null;
            boolean isHoursGreaterThanZero = effortTrackerViewModel.getHours() > 0
                    || String.valueOf(effortTrackerViewModel.getHours())
                            .isEmpty();
            boolean isTaskPhaseNull = effortTrackerViewModel.getTaskPhase() == null;

            // if(effortTrackerViewModel.getTaskType().equals(TaskUtils.DEMAND)
            // ||
            // effortTrackerViewModel.getTaskType().equals(TaskUtils.DEFECT)){
            if (isTaskTypeNull) {
                MessageDialog.openInformation(Display.getCurrent()
                        .getActiveShell(), "Info", "Please select Tasktype");
                return false;
            }
            if (isTaskNoNull) {
                MessageDialog.openInformation(Display.getCurrent()
                        .getActiveShell(), "Info", "Please Enter Task No");
                return false;
            }
            if (isTaskPhaseNull
                    && (effortTrackerViewModel.getTaskType().equals(
                            TaskUtils.DEMAND) || effortTrackerViewModel
                            .getTaskType().equals(TaskUtils.DEFECT))) {
                MessageDialog.openInformation(Display.getCurrent()
                        .getActiveShell(), "Info", "Please select TaskPhase");
                return false;
            }
            if (isStatusNull
                    && effortTrackerViewModel.getTaskType().equals(
                            TaskUtils.DEMAND)
                    || effortTrackerViewModel.getTaskType().equals(
                            TaskUtils.DEFECT)) {
                MessageDialog.openInformation(Display.getCurrent()
                        .getActiveShell(), "Info", "Please select Task status");
                return false;
            }
            if (!isHoursGreaterThanZero
                    && effortTrackerViewModel.getTaskType().equals(
                            TaskUtils.DEMAND)
                    || effortTrackerViewModel.getTaskType().equals(
                            TaskUtils.DEFECT)) {
                MessageDialog.openInformation(Display.getCurrent()
                        .getActiveShell(), "Info", "Please enter hours");
                return false;
            }
            // }

        }

        return true;
    }

    private ControlDecoration getControlDecoration(Control control,
            String hoverText) {
        ControlDecoration controlDecoration = new ControlDecoration(control,
                SWT.LEFT | SWT.TOP);
        controlDecoration.setDescriptionText(hoverText);
        FieldDecoration fieldDecoration = FieldDecorationRegistry.getDefault()
                .getFieldDecoration(FieldDecorationRegistry.DEC_ERROR);
        controlDecoration.setImage(fieldDecoration.getImage());
        return controlDecoration;
    }

   
    
    public static boolean isNumeric(String str)  
    {  
      try  
      {  
        double d = Double.parseDouble(str);  
      }  
      catch(NumberFormatException nfe)  
      {  
        return false;  
      }  
      return true;  
    }

    
    public static void main(String[] args) {
    System.out.println("124".matches("\\d+"));
    }
    
    // TODO write a method which checks the any of the bean field is null or
    // not.If any of the field is null, then return false,

}